import { Table as AntdTable, Button, Input, PaginationProps } from "antd";
import dayjs from "dayjs";
import React, {
  forwardRef,
  ForwardRefRenderFunction,
  useContext,
  useEffect,
  useImperativeHandle,
  useMemo,
  useRef,
  useState,
} from "react";
import { CommonComponentProps } from "@/pages/lowCodeEditorPlus/interface";
import { useSize } from "ahooks";
import { axiosInstance } from "@/interfaces";
import { SyncOutlined } from "@ant-design/icons";
import { SizeType } from "@/types/antd-types";
import TableOperationColumn from "@/pages/lowCodeEditorPlus/materialItems/dataContainer/TableOperationColumn/prod";
import { renderProdComponents } from "@/pages/lowCodeEditorPlus/components/Preview/renderProdComponents";

export interface TableRef {
  getTableData: (page: number, pageSize: number) => void;
  refresh: (page: number, pageSize: number) => void;
}
const Table: ForwardRefRenderFunction<TableRef, Omit<CommonComponentProps, "ref">> = (props, fRef) => {
  const {
    id,
    api,
    children,
    styles,
    pagination,
    showHeaderTool,
    showSearch,
    showFresh,
    buttonGroup,
    size,
    filterFields = [],
  } = props;
  const [dataSource, setDataSource] = useState<Array<Record<string, any>>>([]);
  const [total, setTotal] = useState(0);
  const [current, setCurrent] = useState(1);
  const [loading, setLoading] = useState(false);
  const [filter, setFilter] = useState("");
  const ref = useRef(null);
  const sizeRef = useSize(ref);

  const [pageSize, setPageSize] = useState(pagination ? pagination.pageSize : 10);

  const getData = async (page: number = 1, size: number = 10, filterValue?: string) => {
    if (api) {
      setLoading(true);
      const { url } = api;
      const realFilter = filterValue === undefined ? filter : filterValue
      const res = await axiosInstance.get(url, {
        params: { page, size, filter: realFilter, filterFields: filterFields.join(",") },
      });
      const { data, pager } = res.data;
      setDataSource(data);
      setTotal(pager.total);
      setLoading(false);
    }
  };

  useEffect(() => {
    getData(1, pageSize);
  }, []);

  useImperativeHandle(
    fRef,
    () => {
      return {
        getTableData: (current, pageSize) => {
          getData(current, pageSize);
        },
        refresh:()=>{
          getData(current, pageSize)
        },
      };
    },
    [current, pageSize, filter]
  );

  const paginationConf = pagination
    ? {
        pageSize: pageSize,
        total: total,
        current,
        showTotal: (total: number) => (pagination.showTotal ? `共 ${total} 条` : null),
        showQuickJumper: pagination.showQuickJumper,
        showSizeChanger: pagination.showSizeChanger,
        onChange: (page: number, size: number) => {
          setCurrent(page);
          setPageSize(size);
          getData(page, size);
        },
      }
    : false;

  const tableDataProperties = useMemo(() => {
    return {
      items: dataSource,
    };
  }, [dataSource]);
  const columns = useMemo(() => {
    return React.Children.map(children, (item: any) => {
      const { name, title, dataIndex, id, width, children, type, buttonGroup } = item.props || {};
      if (name === "TableColumn") {
        if (type === "date") {
          return {
            title: title,
            dataIndex: dataIndex,
            render: (value: any) => (value ? dayjs(value).format("YYYY-MM-DD") : null),
            width: width || "auto",
          };
        } else {
          return {
            title: title,
            dataIndex: dataIndex,
            width: width || "auto",
          };
        }
      } else {
        return {
          title,
          width: width || "auto",
          align: "center",
          render: (_: unknown, record: any, index: number) => (
            <TableOperationColumn
              buttonGroup={buttonGroup}
              record={record}
              index={index}
              parentDataProperties={tableDataProperties}
            />
          ),
        };
      }
    });
  }, [children, dataSource]);

  const renderButtonGroup = renderProdComponents(buttonGroup, { ancestorDataProperties: tableDataProperties });
  const rowSizeObj = {
    large: 55,
    middle: 47,
    small: 39,
  };
  const paginationSizeObj = {
    large: 48, //16 + 32,
    middle: 40, //16 + 24
    small: 40,
  };
  const tableHeight = useMemo(() => {
    const rowH = rowSizeObj[(size as SizeType) || "middle"];
    const pH = paginationSizeObj[(size as SizeType) || "middle"];
    const h = sizeRef?.height || 255;
    if (dataSource.length === 0) return undefined;
    if ((dataSource.length + 1) * rowH < h - pH) return undefined; //数据的长度加上表头高度小于容器高度就不展示scroll
    return columns.length > 0 ? h - rowH - pH : h - 33;
  }, [sizeRef, dataSource.length]);
  return (
    <section className="flex flex-col h-full gap-y-3" data-component-id={id}>
      {showHeaderTool && (
        <header className="flex gap-2">
          {showSearch && (
            <Input.Search
              value={filter}
              allowClear
              onClear={()=>getData(1, pageSize, "")}
              onChange={e => setFilter(e.target.value)}
              style={{ width: "200px" }}
              onSearch={()=>{
                setCurrent(1)
                getData(1, pageSize)
              }}
            />
          )}
          <div className="flex flex-1 w-1 gap-1">{renderButtonGroup()}</div>
          {showFresh && <Button shape="circle" icon={<SyncOutlined onClick={() => getData(current, pageSize)} />} />}
        </header>
      )}
      <div ref={ref} className="flex-1 min-h-20" style={styles}>
        <AntdTable
          size={size}
          bordered
          columns={columns}
          dataSource={dataSource}
          rowKey="id"
          loading={loading}
          scroll={{ y: tableHeight }}
          className={dataSource.length > 0 ? "" : "fullHeight"}
          pagination={paginationConf}
        />
      </div>
    </section>
  );
};

export default forwardRef(Table);
